package com.me.chat.mq.listencer;

import com.alibaba.fastjson.JSON;
import com.me.chat.pojo.chat.ChatMessage;
import com.me.chat.pojo.chat.MessageType;
import com.me.chat.pojo.relation.SingleRelation;
import com.me.chat.pojo.relation.SingleRelationReq;
import com.me.chat.pojo.user.UserInfo;
import com.me.chat.service.user.UserService;
import com.me.chat.util.stauts.MessageCode;
import com.me.chat.ws.WsSessionData;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;
import org.springframework.stereotype.Component;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.TextMessage;
import javax.websocket.Session;
import java.io.IOException;
import java.util.Map;

/**
 * ws topic 广量接受 每一个服务节点都会监听到，然后发送出去
 * @Author: qiu
 * @Date: 2021/4/1 15:14
 */
@Component
@Slf4j
public class WsChatListencer {

    @Autowired
    UserService userService;

    @JmsListener(destination = "wsChatTopic",containerFactory ="jmsListenerContainerTopic")
    public void recieve(Message message) throws JMSException {
        if(message instanceof TextMessage){
            TextMessage textMessage = (TextMessage) message;

            String json = null;
            try {
                json = textMessage.getText();
                this.doAction(json);
                log.info("activemq 接受websocket发送者发送的消息："+json);
            } catch (JMSException e) {
                log.error("activemq 在接受websocket 发送者发送的消息的时候出现了异常问题："+e.toString());
                e.printStackTrace();
            }
        }
    }


    private void doAction(String json) {
        MessageType messageType = JSON.parseObject(json, MessageType.class);

        int code = messageType.getStatusCode();

        //根据不同的code执行不同的操作
        switch (code) {
            //200 点对点消息传输处理
            case MessageCode.SINGLE_CHAT:
                this.doSingleChat(messageType,json);
                break;
            //201 好友关联请求传输处理
            case MessageCode.SINGLE_RELATION_REQ:
                this.doSingleRelationReq(messageType,json);
                break;
            //202 好友关联创建传输处理
            case MessageCode.SINGLE_RELATION:
                this.doSingleRelation(messageType);
                break;
            default:
                log.warn("未知的消息类型");
        }

    }

    /**
     * 点对点消息传输监听
     * @param messageType
     * @param json
     */
    private void doSingleChat(MessageType messageType,String json) {

        //获得 websocket 服务中的 session
        Map<String, Session> sessionMap = WsSessionData.sessionMap;

        ChatMessage chatMessage = messageType.getChatMessage();
        //代表点对点通讯
        if(chatMessage.getTargetType() == 1) {
            //得到接收者
            String receiver = chatMessage.getTargetId();
            //在本地该节点中寻找 session
            Session session = sessionMap.get(receiver);
            //如果该节点中存在 该接收者 则发送出去
            if(session != null){
                try {
                    session.getBasicRemote().sendText(json);
                    log.info("接收者："+receiver+" 在线，ws给接收者发送聊天信息");
                } catch (IOException e) {
                    log.info("websocket给接收者开始发送过程中出现了问题："+ e.toString());
                    e.printStackTrace();
                }

            }else {
                log.info("接收者："+receiver+" 在该节点中未在线："+json);
            }
        }
    }

    /**
     * 好友请求分发处理
     * @param messageType
     * @param json
     */
    private void doSingleRelationReq(MessageType messageType,String json) {

        //获得 websocket 服务中的 session
        Map<String, Session> sessionMap = WsSessionData.sessionMap;

        SingleRelationReq singleRelationReq = messageType.getSingleRelationReq();
        //得到目标用户
        String targetId = singleRelationReq.getTargetId();
        //在本地该节点中寻找 session
        Session session = sessionMap.get(targetId);
        //如果该节点中存在 该接收者 则发送出去
        if(session != null){
            try {
                session.getBasicRemote().sendText(json);
                log.info("接收者："+targetId+" 在线，ws给接收者发送好友请求");
            } catch (IOException e) {
                log.info("websocket给接收者开始发送过程中出现了问题："+ e.toString());
                e.printStackTrace();
            }

        }else {
            log.info("接收者："+targetId+" 在该节点中未在线："+json);
        }
    }


    /**
     * 好友关联创建完毕 分发通知
     * @param messageType
     */
    private void doSingleRelation(MessageType messageType) {
        //获得 websocket 服务中的 session
        Map<String, Session> sessionMap = WsSessionData.sessionMap;
        SingleRelation singleRelation = messageType.getSingleRelation();
        //发送方已经静态渲染了一次，将target通过分发来通知
        String targetId = singleRelation.getTargetId();
        String oldOwnerId = singleRelation.getOwnerId();
        //发送给接受者的通知需要渲染好友列表，则ownerId 和 targetId的位置需要反一下
        singleRelation.setOwnerId(targetId);
        singleRelation.setTargetId(oldOwnerId);

        //通过oldOwnerId获得用户详细信息
        UserInfo userInfo = userService.getUserInfoNoSetCatch(oldOwnerId);
        singleRelation.setTargetUserInfo(userInfo);

        //重新json化成字符串
        String json = JSON.toJSONString(messageType);

        //在本地该节点中寻找 session
        Session session = sessionMap.get(targetId);

        //如果该节点中存在 该接收者 则发送出去
        if(session != null){
            try {
                session.getBasicRemote().sendText(json);
                log.info("接收者："+targetId+" 在线，ws给接收者发送新好友");
            } catch (IOException e) {
                log.info("websocket给接收者开始发送过程中出现了问题："+ e.toString());
                e.printStackTrace();
            }

        }else {
            log.info("接收者："+targetId+" 在该节点中未在线："+json);
        }

    }
}
